#[cfg(test)]
mod tests {
    use crate::evaluator::*;
    use crate::expr::*;
    use crate::parser::*;
    use crate::tokstr::*;
    #[test]
    fn bin_expr() {
        assert_eq!("1+2*3/4", "1+2*3/4");
    }

    #[test]
    fn tokens() {
        let t = TokStr::new("1+2*sin(b)".to_string()); // 1+2*sin(b) 1+2-3*4/5^6
                                                       // let mut p = Parser::new(t);
        assert_eq!(
            t.collect::<Vec<Expr>>(),
            vec![
                Expr::Csti(1,),
                Expr::Add(None, None,),
                Expr::Csti(2,),
                Expr::Mul(None, None,),
                Expr::Sin(None,),
                Expr::Bra,
                Expr::Var("b".to_string(),),
                Expr::Ket,
            ]
        )
    }
    #[test]
    fn four_operation() {
        let t = TokStr::new("1+2-3*4/5^6".to_string());
        let mut p = Parser::new(t);
        // println!("{:#?}", t.collect::<Vec<Expr>>());

        assert_eq!(
            format!("{}", p.parse_expr().unwrap()),
            "[[1+2]-[[3*4]/[5^6]]]"
        );
    }

    #[test]
    fn trangle_operation() {
        let t = TokStr::new("1+2*3/4".to_string());
        let mut p = Parser::new(t);
        assert_eq!(format!("{}", p.parse_expr().unwrap()), "[1+[[2*3]/4]]");

        let t = TokStr::new("1+2*3/4^5".to_string());
        let mut p = Parser::new(t);
        assert_eq!(format!("{}", p.parse_expr().unwrap()), "[1+[[2*3]/[4^5]]]");

        let t = TokStr::new("1+2*sin(b)".to_string());
        let mut p = Parser::new(t);
        assert_eq!(format!("{}", p.parse_expr().unwrap()), "[1+[2*sin(b)]]");

        let t = TokStr::new("3*4/cos(b)".to_string());
        let mut p = Parser::new(t);
        assert_eq!(format!("{}", p.parse_expr().unwrap()), "[[3*4]/cos(b)]");

        let t = TokStr::new("sin(a+b)".to_string());
        let mut p = Parser::new(t);
        assert_eq!(format!("{}", p.parse_expr().unwrap()), "sin([a+b])");

        let t = TokStr::new("tan(a+b)".to_string());
        let mut p = Parser::new(t);
        assert_eq!(format!("{}", p.parse_expr().unwrap()), "tan([a+b])");
    }

    #[test]
    fn test_eval() {
        use std::collections::HashMap;
        let t = TokStr::new("x^2".to_string());
        let mut p = Parser::new(t);
        let mut e: HashMap<String, Expr> = HashMap::new();
        e.insert("x".to_string(), Expr::Cstf(3.0));
        assert_eq!(Evaluator::eval_expr(&p.parse_expr().unwrap(), &e), 9.0);

        let t = TokStr::new("1+2-3*4/5".to_string());
        let mut p = Parser::new(t);
        let mut e: HashMap<String, Expr> = HashMap::new();
        e.insert("x".to_string(), Expr::Cstf(3.0));
        assert_eq!(
            Evaluator::eval_expr(&p.parse_expr().unwrap(), &e),
            1.0 + 2.0 - 3.0 * 4.0 / 5.0
        );
    }
    #[test]
    fn test_evaluate_differ() {
        let t = TokStr::new("tan(a)".to_string());
        let mut p = Parser::new(t);
        assert_eq!(
            format!(
                "{}",
                Evaluator::derivative(p.parse_expr().unwrap(), &"a".to_string())
            ),
            "[[[[cos(a)*1]*cos(a)]-[sin(a)*[-sin(a)*1]]]/[cos(a)^2]]"
        );
    }
}
